/**
 * @file    If_comm.c
 * @brief   串口通信接口
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-20
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 *  
 *    COM_EMS  ->  USART2
 *    COM_PARALLEL  ->  USART6
 *    COM_PCS   ->  USART1 
 *    COM_LCD   ->  USART0
 *    COM_BLUE  ->  USART5
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-20 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */
/* includes ------------------------------------------------------------------*/
#include "If_com.h"
#include "drv_uart.h"
#include "drv_gpt.h"
#include "mcu_type.h"
#include "drv_gpio.h"
/* macro/define --------------------------------------------------------------*/
#define COM_RECV_TIMEOUT          (30)

/* typedef -------------------------------------------------------------------*/
typedef enum
{
	COM_RECV_IDLE  ,  /*!< 空闲状态*/
	COM_RECVING    ,  /*!< 正在接受 */ 
	COM_RECV_COMP  ,  /*!< 接受完成 */ 
	COM_RECV_STOP  ,  /*!< 停止接收 */
}com_state_type;

typedef struct 
{
	uint8_t uart_id;
	com_state_type recv_state;
	uint16_t recv_idx;
	uint8_t data_buf[COM_RX_BUF_SIZE];
	uint16_t timeout_cnt;
}com_obj_type;
/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/

/* global variables ----------------------------------------------------------*/
static volatile com_obj_type com_obj_buf[COM_ID_MAX] = 
{
	{DRV_UART6 , COM_RECV_IDLE , 0 , {0} , 0} , 
	{DRV_UART7 , COM_RECV_IDLE , 0 , {0} , 0} , 
	{DRV_UART0 , COM_RECV_IDLE , 0 , {0} , 0} , 
	{DRV_UART5 , COM_RECV_IDLE , 0 , {0} , 0} , 
	{DRV_UART2 , COM_RECV_IDLE , 0 , {0} , 0} , 
	{DRV_UART1 , COM_RECV_IDLE , 0 , {0} , 0} , 
};

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief COM 配置初始化
 */
void If_com_cfg_init(void)
{
	drv_gpt_init(DRV_GPT1 , 1 , &If_com_time_irq);
}

/**
 * @brief  COM 初始化COM驱动
 * @param  com_id
 */
void If_com_init_drv(uint8_t com_id , uint32_t baudrate)
{
	if(com_id >= COM_ID_MAX)
		return ;

	drv_uart_init(com_obj_buf[com_id].uart_id , baudrate);
	drv_uart_set_rx_cb(com_obj_buf[com_id].uart_id , &If_com_uart_recv_irq);

	If_com_start_recv(com_id);
}

/**
 * @brief  串口接收中断
 * @param  com_id : COM ID号
 * @param  data : 接收数据
 */	
	
void If_com_uart_recv_irq(uint8_t com_id , uint8_t data)
{
	uint8_t i = 0;
	uint8_t idx = 0;
	if(com_id >= DRV_UART_MAX)
		return ;
	/** 映射UART口 */
	for(i = 0;i < COM_ID_MAX; ++ i)
	{
		if(com_id == com_obj_buf[i].uart_id)
		{
			idx = i;
			break;
		}
	}
	
	if(COM_RECV_IDLE == com_obj_buf[idx].recv_state)
	{
		com_obj_buf[idx].recv_idx = 0;
		com_obj_buf[idx].timeout_cnt = 0;
		com_obj_buf[idx].data_buf[0] = data;
		++ com_obj_buf[idx].recv_idx;
		com_obj_buf[idx].recv_state = COM_RECVING;
	}
	else if(COM_RECVING == com_obj_buf[idx].recv_state)
	{
		if(com_obj_buf[idx].recv_idx < COM_RX_BUF_SIZE)
		{
			com_obj_buf[idx].data_buf[com_obj_buf[idx].recv_idx] = data;
			
			++ com_obj_buf[idx].recv_idx;
			
			com_obj_buf[idx].timeout_cnt = 0;
		}
	}
	else
	{
		;
	}
}

/**
 * @brief  定时中断
 * @param  time_cycle
 */
void If_com_time_irq(uint32_t time)
{
	uint8_t i = 0;
	
	for(i = 0;i < COM_ID_MAX; ++ i)
	{
		if(com_obj_buf[i].recv_state == COM_RECVING)
		{
			com_obj_buf[i].timeout_cnt ++;
			if(com_obj_buf[i].timeout_cnt >= COM_RECV_TIMEOUT)
			{
				 com_obj_buf[i].recv_state = COM_RECV_COMP;
			}
		}
	}
}

/**
 * @brief  接收完成
 * @param  com_id : COM ID
 */
uint8_t If_com_recv_comp(uint8_t com_id)
{
	if(com_id >= COM_ID_MAX)
		return FALSE;
	
	if(COM_RECV_COMP == com_obj_buf[com_id].recv_state)
	{
		return TRUE;
	}

	return FALSE;
}

/**
 * @brief  获取接收数量
 * @param  com_id : ID
 * @return uint16_t : 接收的数量
 */
uint16_t If_com_get_recv_num(uint8_t com_id)
{
	if(com_id >= COM_ID_MAX)
		return 0;
	
	return com_obj_buf[com_id].recv_idx;
}

/**
 * @brief  获取接收缓冲区的数据
 * @param  com_id : ID
 * @param  data_buf : 数据缓冲区
 * @return uint16_t : 接收的数量
 */
uint16_t If_com_get_recv_buf(uint8_t com_id ,uint8_t *data_buf ,uint16_t recv_num)
{
	uint16_t i = 0;
	
	if(com_id >= COM_ID_MAX)
		return 0;
	
	for( i = 0;(i < recv_num) && (i < COM_RX_BUF_SIZE); ++ i)
	{
		data_buf[i] = com_obj_buf[com_id].data_buf[i];
	}
	
	return com_obj_buf[com_id].recv_idx;
}

/**
 * @brief  发送字符串
 * @param  com_id : COM ID
 * @param  send_buf : 发送缓冲区
 * @param  send_size : 发送数量
 */
void If_com_send_str(uint8_t com_id , uint8_t *send_buf , uint16_t send_size)
{
	if(com_id >= COM_ID_MAX)
		return ;
	
	drv_uart_send_str(com_obj_buf[com_id].uart_id , send_buf , send_size);
}

/**
 * @brief  启动接收
 * @param  com_id : 接收ID
 */
void If_com_start_recv(uint8_t com_id)
{
	if(com_id >= COM_ID_MAX)
		return ;
	
	com_obj_buf[com_id].recv_state = COM_RECV_IDLE;
	com_obj_buf[com_id].recv_idx = 0;
	com_obj_buf[com_id].timeout_cnt = 0;
}

/**
 * @brief  重启接收
 * @param  com_id : 接收ID
 */
void If_com_reset_recv(uint8_t com_id)
{
	if(com_id >= COM_ID_MAX)
		return ;
	
	switch(com_id)
	{
		case COM_PARALLEL:
			drv_gpio_reset_pin(RS485_DE2_PORT , RS485_DE2_PIN);
			break;
		case COM_PCS:
			drv_gpio_reset_pin(RS485_DE1_PORT , RS485_DE1_PIN);
			break;
		case COM_LCD:
			break;
		case COM_BLUE:
			break;
	}
}

/**
 * @brief  重启初始化
 * @param  com_id : 接收ID
 */
void If_com_deinit(uint8_t com_id)
{
	if(com_id >= COM_ID_MAX)
		return ;
	
	drv_uart_deinit(com_obj_buf[com_id].uart_id);
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
 
/*************************(C)Copyright file end *******************************/
